package gen.desktop.components;

import gen.core.exceptions.GenException;
import gen.core.managers.SqlManager;
import gen.core.managers.TemplateManager;
import gen.core.models.Sql;
import gen.core.models.Template;
import gen.core.utils.GenUtils;
import gen.desktop.Application;

import java.awt.Dimension;
import java.awt.Font;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.ItemEvent;
import java.awt.event.ItemListener;
import java.io.ByteArrayInputStream;
import java.sql.Connection;

import javax.swing.DefaultComboBoxModel;
import javax.swing.ImageIcon;
import javax.swing.JButton;
import javax.swing.JComboBox;
import javax.swing.JFileChooser;
import javax.swing.JLabel;
import javax.swing.JOptionPane;
import javax.swing.JSeparator;
import javax.swing.JToolBar;
import javax.swing.SwingConstants;

import org.apache.commons.io.FileUtils;
import org.apache.commons.io.output.ByteArrayOutputStream;
import org.apache.commons.lang.ArrayUtils;
import org.apache.commons.lang.StringUtils;

public class TemplateToolBar extends JToolBar {
	private static final long serialVersionUID = 1L;
	private JComboBox comboBox;
	private TemplateToolBarResponser responser;
	private final String CATAGORY;
	private JButton saveButton;
	private JButton saveAsButton;
	private JButton deleteButton;
	private JButton importButton;
	private JButton exportButton;

	public TemplateToolBar(TemplateToolBarResponser responser, String Catagory) {
		this.responser = responser;
		CATAGORY = Catagory;

		JLabel label = new JLabel("载入模版：");
		label.setHorizontalAlignment(SwingConstants.LEFT);
		add(label);

		comboBox = new JComboBox();
		comboBox.setMaximumRowCount(10);
		comboBox.setFont(new Font("宋体", Font.PLAIN, 12));
		add(comboBox);

		JSeparator separator = new JSeparator();
		separator.setOrientation(SwingConstants.VERTICAL);
		add(separator);

		saveButton = new JButton("保存");
		saveButton.setIcon(new ImageIcon(TemplateToolBar.class.getResource("/gen/desktop/icons/size16x16/disk.png")));
		saveButton.setToolTipText("");
		saveButton.setFont(new Font("宋体", Font.PLAIN, 12));
		add(saveButton);

		saveAsButton = new JButton("另存为");
		saveAsButton.setIcon(new ImageIcon(TemplateToolBar.class.getResource("/gen/desktop/icons/size16x16/save_as.png")));
		saveAsButton.setFont(new Font("宋体", Font.PLAIN, 12));
		add(saveAsButton);

		deleteButton = new JButton("删除");
		deleteButton.setIcon(new ImageIcon(TemplateToolBar.class.getResource("/gen/desktop/icons/size16x16/delete.png")));
		add(deleteButton);

		importButton = new JButton("导入");
		importButton.setIcon(new ImageIcon(TemplateToolBar.class.getResource("/gen/desktop/icons/size16x16/import.png")));
		add(importButton);

		exportButton = new JButton("导出");
		exportButton.setIcon(new ImageIcon(TemplateToolBar.class.getResource("/gen/desktop/icons/size16x16/export.png")));
		add(exportButton);

		init();
	}

	public void init() {
		loadTemplateListToComboBox();

		// 下拉框调整到适合的宽度
		Dimension aDimension = comboBox.getPreferredSize();
		aDimension.setSize(aDimension.getWidth(), aDimension.getHeight());
		comboBox.setMaximumSize(aDimension);

		/**
		 * 响应模板下拉框，切换模板输入框中的内容
		 */
		comboBox.addItemListener(new ItemListener() {
			public void itemStateChanged(ItemEvent e) {
				if (e.getStateChange() == java.awt.event.ItemEvent.SELECTED) {
					Template aTemplate = (Template) e.getItem();
					responser.setTemplateText(aTemplate.getContent());
					
					if(responser.getSqlText() != null){
						Connection conn = null;
						SqlManager aSqlManager = new SqlManager();
						try{
							conn = Application.getSqliteClient().createConnection();
							
							Sql[] sqls = aSqlManager.list(conn, aTemplate.getId());
							if(sqls.length > 0){
								responser.setSqlText(sqls[0].getContent());
							}else{
								responser.setSqlText("");
							}
						}catch(Exception ex){
							JOptionPane.showMessageDialog(null, ex.getMessage(), "切换模版失败！", JOptionPane.ERROR_MESSAGE);
							return;
						} finally {
							GenUtils.closeConnection(conn);
						}
					}
				}
			}
		});

		/**
		 * 响应保存按钮，保存模板到数据库中
		 */
		saveButton.addActionListener(new ActionListener() {
			public void actionPerformed(ActionEvent e) {
				Template selectedTemplate = (Template) comboBox.getSelectedItem();
				Connection conn = null;
				TemplateManager aTemplateManager = new TemplateManager();
				SqlManager aSqlManager = new SqlManager();

				try {
					conn = Application.getSqliteClient().createConnection();
					if (StringUtils.isBlank(selectedTemplate.getId())) {
						throw new GenException(null, "模版名不能为空！");
					}

					Template aTemplate = aTemplateManager.load(conn, selectedTemplate.getId());
					aTemplate.setContent(responser.getTemplateText());
					aTemplateManager.save(conn, aTemplate);
					
					if(responser.getSqlText() != null){
						Sql sql = null;
						Sql[] sqls = aSqlManager.list(conn, selectedTemplate.getId());
						if(sqls.length > 0){
							sql = sqls[0];
						}else{
							sql = new Sql();
							sql.setCatagory(CATAGORY);
							sql.setOwner(Application.getOwner());
							sql.setTemplateId(selectedTemplate.getId());
						}					
						sql.setContent(responser.getSqlText());
						aSqlManager.save(conn, sql);
					}
					
					conn.commit();

					selectedTemplate.setContent(aTemplate.getContent());
				} catch (Exception ex) {
					JOptionPane.showMessageDialog(null, ex.getMessage(), "模版保存失败！", JOptionPane.ERROR_MESSAGE);
					return;
				} finally {
					GenUtils.closeConnection(conn);
				}
			}
		});

		/**
		 * 响应另存为按钮，创建新的模版并存入数据库
		 */
		saveAsButton.addActionListener(new ActionListener() {
			public void actionPerformed(ActionEvent e) {
				// 保存新模版
				Connection conn = null;
				TemplateManager aTemplateManager = new TemplateManager();
				Template aTemplate = new Template();
				SqlManager aSqlManager = new SqlManager();

				try {
					// 提示输入新模版的名称
					String aName = JOptionPane.showInputDialog(null, "请输入新模版的名称:");
					if (aName == null) // 因为点击了取消取消，所以方法直接静默返回
						return;
					if (StringUtils.isBlank(aName)) {
						throw new GenException(null, "无效的模版名称！");
					}

					conn = Application.getSqliteClient().createConnection();

					aTemplate.setName(aName);
					aTemplate.setCatagory(CATAGORY);
					aTemplate.setContent(responser.getTemplateText());
					aTemplate.setOwner(Application.getOwner());
					aTemplateManager.save(conn, aTemplate);
					
					if(responser.getSqlText() != null){
						Sql sql = new Sql();
						sql.setCatagory(CATAGORY);
						sql.setOwner(Application.getOwner());
						sql.setTemplateId(aTemplate.getId());
						sql.setContent(responser.getSqlText());
						aSqlManager.save(conn, sql);
					}

					conn.commit();
				} catch (Exception ex) {
					JOptionPane.showMessageDialog(null, ex.getMessage(), "模版另存失败！", JOptionPane.ERROR_MESSAGE);
					return;
				} finally {
					GenUtils.closeConnection(conn);
				}

				// 刷新模版下拉框，并置下拉框当前项为新保存的模版
				loadTemplateListToComboBox();
				for (int i = 1; i < comboBox.getItemCount(); i++) {
					Template curTemplate = (Template) comboBox.getItemAt(i);
					if (curTemplate.getId().equals(aTemplate.getId())) {
						comboBox.setSelectedIndex(i);
					}
				}
			}
		});

		/**
		 * 响应删除按钮，删除选中的模版
		 */
		deleteButton.addActionListener(new ActionListener() {
			public void actionPerformed(ActionEvent e) {
				Connection conn = null;
				Template selectedTemplate = (Template) comboBox.getSelectedItem();
				TemplateManager aTemplateManager = new TemplateManager();
				SqlManager aSqlManager = new SqlManager();

				try {
					conn = Application.getSqliteClient().createConnection();
					if (StringUtils.isBlank(selectedTemplate.getId())) {
						return;
					}

					aTemplateManager.delete(conn, selectedTemplate.getId());
					if(responser.getSqlText() != null){
						Sql[] sqls = aSqlManager.list(conn, selectedTemplate.getId());
						if(sqls.length > 0){
							aSqlManager.delete(conn, sqls[0].getId());
						}
					}
					
					conn.commit();
				} catch (Exception ex) {
					JOptionPane.showMessageDialog(null, ex.getMessage(), "模版删除失败！", JOptionPane.ERROR_MESSAGE);
					return;
				} finally {
					GenUtils.closeConnection(conn);
				}

				comboBox.removeItem(selectedTemplate);
			}
		});

		/**
		 * 响应导出按钮，导出所有模版
		 */
		exportButton.addActionListener(new ActionListener() {
			public void actionPerformed(ActionEvent e) {
				Connection conn = null;
				TemplateManager aTemplateManager = new TemplateManager();

				try {
					JFileChooser chooser = new JFileChooser();
					if (chooser.showSaveDialog(null) != JFileChooser.APPROVE_OPTION)
						return;
					
					conn = Application.getSqliteClient().createConnection();
					Template[] array = aTemplateManager.list(conn, Application.getOwner(), CATAGORY);

					ByteArrayOutputStream out = new ByteArrayOutputStream();
					aTemplateManager.exportJson(out, array);
					FileUtils.writeStringToFile(chooser.getSelectedFile(), out.toString(), "utf8");

					JOptionPane.showMessageDialog(null, "文件导出完成.", "导出", JOptionPane.PLAIN_MESSAGE);
				} catch (Exception ex) {
					JOptionPane.showMessageDialog(null, ex.getMessage(), "模版导出失败！", JOptionPane.ERROR_MESSAGE);
					return;
				} finally {
					GenUtils.closeConnection(conn);
				}
			}
		});

		/**
		 * 响应导入按钮，导入所有模版
		 */
		importButton.addActionListener(new ActionListener() {
			public void actionPerformed(ActionEvent e) {
				Connection conn = null;
				TemplateManager aTemplateManager = new TemplateManager();

				try {
					JFileChooser chooser = new JFileChooser();
					if (chooser.showOpenDialog(null) != JFileChooser.APPROVE_OPTION)
						return;
					
					ByteArrayInputStream in = new ByteArrayInputStream(FileUtils.readFileToString(chooser.getSelectedFile(), "utf8").getBytes("utf8"));
					Template[] array = aTemplateManager.importJson(in);
					
					conn = Application.getSqliteClient().createConnection();
					for(Template aTemplate : array){
						aTemplate.setId("");
						aTemplateManager.save(conn, aTemplate);
					}
					
					conn.commit();

					loadTemplateListToComboBox();
					JOptionPane.showMessageDialog(null, "文件导入完成.", "导入", JOptionPane.PLAIN_MESSAGE);
				} catch (Exception ex) {
					JOptionPane.showMessageDialog(null, ex.getMessage(), "模版导入失败！", JOptionPane.ERROR_MESSAGE);
					return;
				} finally {
					GenUtils.closeConnection(conn);
				}
			}
		});
	}

	private void loadTemplateListToComboBox() {
		TemplateManager aTemplateManager = new TemplateManager();
		Connection conn = null;
		try {
			conn = Application.getSqliteClient().createConnection();
			Template[] templateArray = aTemplateManager.list(conn, Application.getOwner(), CATAGORY);
			comboBox.setModel(new DefaultComboBoxModel(ArrayUtils.add(templateArray, 0, new Template())));
		} finally {
			GenUtils.closeConnection(conn);
		}
	}

	public JComboBox getComboBox() {
		return comboBox;
	}

	public JButton getBtnSaveButton() {
		return saveButton;
	}

	public JButton getBtnSaveAsButton() {
		return saveAsButton;
	}

	public JButton getBtnDeleteButton() {
		return deleteButton;
	}
}
